package com.silence.springboot.service.impl;


import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.silence.springboot.constants.StringConstants;
import com.silence.springboot.convert.LoginConvert;
import com.silence.springboot.convert.UserBaseInfoConvert;
import com.silence.springboot.dao.LoginDao;
import com.silence.springboot.dao.UserBaseInfoDao;
import com.silence.springboot.entity.LoginEntity;
import com.silence.springboot.entity.UserBaseInfoEntity;
import com.silence.springboot.enums.ResultCode;
import com.silence.springboot.exception.ApiException;
import com.silence.springboot.mapper.UserBaseInfoMapper;
import com.silence.springboot.service.UserBaseInfoService;
import com.silence.springboot.utils.JwtUtil;
import com.silence.springboot.vo.input.SearchByConditionInput;
import com.silence.springboot.vo.input.UserBaseInfoInput;
import com.silence.springboot.vo.output.QueryUserBaseInfoByTokenOutput;
import com.silence.springboot.vo.output.UserBaseInfoOutput;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * 用户基础信息表 服务层实现。
 *
 * @author mybatis-flex-helper automatic generation
 * @since 1.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserBaseInfoServiceImpl extends ServiceImpl<UserBaseInfoMapper, UserBaseInfoEntity> implements UserBaseInfoService {

    /**
     * 用户基础信息表 数据访问层接口
     */
    private final UserBaseInfoDao userBaseInfoDao;

    /**
     * 登录系统表 数据访问层接口
     */
    private final LoginDao loginDao;

    /**
     * 用户基础信息表 转换器接口
     */
    private final UserBaseInfoConvert userBaseInfoConvert;

    /**
     * 登录系统入参转换
     */
    private final LoginConvert loginConvert;

    /**
     * 根据token查询用户信息
     *
     * @param token token
     * @return 用户信息
     */
    @Override
    public QueryUserBaseInfoByTokenOutput queryUserBaseInfoByToken(String token) {
        log.info("请求头中的 token 为：{}", token);
        // 解析 token
        Long loginId = JwtUtil.getUserId(token);
        // 查询用户信息
        UserBaseInfoEntity userBaseInfoEntity = userBaseInfoDao.queryUserBaseInfoByUserId(loginId);
        if (Objects.isNull(userBaseInfoEntity)) {
            throw new ApiException(ResultCode.LOGIN_USER_TOKEN_ERROR);
        }
        // 返回用户信息
        return userBaseInfoConvert.toQueryUserBaseInfoByTokenOutput(userBaseInfoEntity);
    }

    /**
     * 新增用户基础信息
     *
     * @param input 用户基础信息输入类
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addUserBaseInfo(UserBaseInfoInput input) {
        LoginEntity selectEntity = loginDao.selectOneByQuery(input.getUsername());
        if (Objects.nonNull(selectEntity)) {
            throw new ApiException(ResultCode.LOGIN_USER_USERNAME_EXIST);
        }
        // 新增用户基础信息
        LoginEntity loginEntity = loginConvert.addUserBaseInfoInputToLoginEntity(input);
        loginDao.insert(loginEntity);
        // 获取登录id
        LoginEntity databaseEntity = loginDao.selectOneByQuery(input.getUsername());
        if (Objects.isNull(databaseEntity)) {
            throw new ApiException(ResultCode.LOGIN_USER_NOT_FOUND);
        }
        Long loginId = databaseEntity.getId();
        // 新增用户基础信息
        UserBaseInfoEntity userBaseInfoEntity = userBaseInfoConvert.addUserBaseInfoInputToUserBaseInfoEntity(input);
        userBaseInfoEntity.setLoginId(loginId);
        userBaseInfoEntity.setLoginFlag("2");
        userBaseInfoDao.insertOrUpdate(userBaseInfoEntity);
        log.info("新增用户基础信息成功");
    }

    /**
     * 修改用户基础信息
     *
     * @param input 用户基础信息输入类
     */
    @Override
    public void updateUserBaseInfo(UserBaseInfoInput input) {
        String id;
        if (StringUtils.isNotBlank(input.getId())) {
            id = input.getId();
        } else {
            String token = StringConstants.AUTHORIZATION_HEADER.concat(input.getToken());
            // 根据 Token 查询用户信息
            UserBaseInfoEntity selectEntity = userBaseInfoDao.queryUserBaseInfoByToken(token);
            if (Objects.isNull(selectEntity)) {
                throw new ApiException(ResultCode.LOGIN_USER_NOT_FOUND);
            }
            id = selectEntity.getId().toString();
        }
        // 修改用户基础信息
        UserBaseInfoEntity userBaseInfoEntity = userBaseInfoConvert.updateToUserBaseInfoEntity(input.setId(id));
        userBaseInfoDao.insertOrUpdate(userBaseInfoEntity);
    }

    /**
     * 删除用户基础信息
     *
     * @param id 用户基础信息id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Long id) {
        // 查询用户基础信息
        UserBaseInfoEntity userBaseInfoEntity = userBaseInfoDao.selectOneById(id);
        if (Objects.isNull(userBaseInfoEntity)) {
            throw new ApiException(ResultCode.LOGIN_USER_NOT_FOUND);
        }
        // 删除登录系统表
        loginDao.deleteById(userBaseInfoEntity.getLoginId());
        // 删除用户基础信息
        userBaseInfoDao.deleteById(id);
        log.info("删除用户基础信息成功，用户id为：{}", id);
    }

    /**
     * 批量删除用户基础信息
     *
     * @param ids 用户基础信息id列表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatchByIds(List<Long> ids) {
        // 查询用户基础信息
        List<UserBaseInfoEntity> userBaseInfoEntityList = userBaseInfoDao.selectListByIds(ids);
        // 删除用户基础信息
        List<Long> loginIdList = userBaseInfoEntityList.stream().map(UserBaseInfoEntity::getLoginId).toList();
        loginDao.deleteBatchByIds(loginIdList);
        // 删除登录系统表
        userBaseInfoDao.deleteBatchByIds(ids);
    }

    /**
     * 根据条件查询用户基础信息
     *
     * @param input 用户基础信息输入类
     * @return 用户基础信息列表
     */
    @Override
    public Page<UserBaseInfoOutput> searchByCondition(SearchByConditionInput input) {
        // 转换查询条件
        UserBaseInfoEntity convertEntity = userBaseInfoConvert.searchByConditionInputToUserBaseInfoEntity(input);
        // 查询用户基础信息
        Page<UserBaseInfoEntity> page = userBaseInfoDao.selectListByQuery(input.getPageNum(), input.getPageSize(), convertEntity);
        // 转换查询结果
        return userBaseInfoConvert.toPageUserBaseInfoOutput(page);
    }
}